import { Vue, Prop, Component } from "vue-property-decorator";
import { oneOf } from '../utils/assist';

@Component
export default class Anes extends Vue {
  constructor() {
    super();
    /* 	this.maskClosable =
        !this.$IVIEW || this.$IVIEW.modal.maskClosable === ""
          ? true
          : (this.$IVIEW.modal.maskClosable as boolean); */
  }

  @Prop({ type: [String, Number], default: "default" }) size!: string | number;
  @Prop({ type: Boolean }) transfer?: boolean
  @Prop({
    type: String,
    validator(value: string) {
      return oneOf(value, ['_blank', '_self', '_parent', '_top']);
    },
    default: "_self"

  })
  target!: string;
  @Prop({ type: [Object, String] }) to!: object | string
  @Prop({ type: Boolean, default: false }) replace!: boolean
  @Prop({ type: Boolean, default: false }) append!: boolean

  isServer = false;// Vue.prototype.$isServer;
  transferIndex = 0;

  transferIncrease() {
    this.transferIndex++;
  }

  dispatch<T>(eventName: string, params: any) {
    let parent = this.$parent;
    while (parent) {
      if (parent as unknown as T) {
        parent.$emit.apply(parent, [eventName, params]);
        break;
      }
      parent = parent.$parent;
    }

  }

  broadcastLoop(vue: Vue, componentName: string, eventName: string, params: any[]) {
    if (vue.$children) {
      vue.$children.forEach(child => {
        const name = (child.$options as any)._componentTag.toUpperCase();
        if (name === componentName.toUpperCase()) {
          child.$emit.apply(child, [eventName, params]);
        } else {
          // todo 如果 params 是空数组，接收到的会是 undefined
          this.broadcastLoop(child, componentName, eventName, params);
        }
      });
    }
  }

  broadcast(componentName: string, eventName: string, params: any[]) {
    this.broadcastLoop(this, componentName, eventName, params)
  }

  created() {
    if (this.$IVIEW) {
      if (this.$IVIEW.size)
        this.size = this.$IVIEW.size;
      if (this.$IVIEW.transfer)
        this.transfer = (this.$IVIEW.transfer as boolean)
    }
  }

  l(key: string): string {
    return key;
  }
  on() {
    if (!this.isServer && document.addEventListener) {
      return function (element: any, event: string, handler: Function, useCapture = false) {
        if (element && event && handler) {
          element.addEventListener(event, handler, useCapture);
        }
      };
    } else {
      return function (element: any, event: string, handler: Function) {
        if (element && event && handler) {
          element.attachEvent('on' + event, handler);
        }
      };
    }
  }


  off() {
    if (!this.isServer && document.removeEventListener) {
      return function (element: any, event: string, handler: Function, useCapture = false) {
        if (element && event) {
          element.removeEventListener(event, handler, useCapture);
        }
      };
    } else {
      return function (element: any, event: string, handler: Function) {
        if (element && event) {
          element.detachEvent('on' + event, handler);
        }
      };
    }
  }


  get linkUrl() {
    const type = typeof this.to;
    if (type !== 'string') {
      return null;
    }
    if ((this.to as string).includes('//')) {
      /* Absolute URL, we do not need to route this */
      return this.to;
    }
    const router = this.$router;
    if (router) {
      const current = this.$route;
      const route = router.resolve(this.to, current, this.append);
      return route ? route.href : this.to;
    }
    return this.to;
  }



  handleToClick(newWindow = false) {
    const router = this.$router;
    if (newWindow) {
      let to = this.to;
      if (router) {
        const current = this.$route;
        const route = router.resolve(this.to, current, this.append);
        to = route ? route.href : this.to;
      }
      window.open(to as string);
    } else {
      if (router && this.to) {
        this.replace ? this.$router.replace(this.to) : this.$router.push(this.to);
      } else {
        window.location.href = this.to as string;
      }
    }
  }
  handleCheckClick(event: Event, newWindow = false) {
    if (this.to) {
      if (this.target === '_blank') {
        return false;
      } else {
        event.preventDefault();
        this.handleToClick(newWindow);
      }
    }
  }

  /*   beforeCreate:function(){
      console.log('beforeCreate:刚刚new Vue()之后，这个时候，数据还没有挂载呢，只是一个空壳')           
      console.log(this.msg)//undefined
      console.log(document.getElementsByClassName("myp")[0])//undefined
  },
  created:function(){
      console.log('created:这个时候已经可以使用到数据，也可以更改数据,在这里更改数据不会触发updated函数')
      this.msg+='!!!'
      console.log('在这里可以在渲染前倒数第二次更改数据的机会，不会触发其他的钩子函数，一般可以在这里做初始数据的获取')
      console.log('接下来开始找实例或者组件对应的模板，编译模板为虚拟dom放入到render函数中准备渲染')
  },
  beforeMount:function(){
      console.log('beforeMount：虚拟dom已经创建完成，马上就要渲染,在这里也可以更改数据，不会触发updated')
      this.msg+='@@@@'
      console.log('在这里可以在渲染前最后一次更改数据的机会，不会触发其他的钩子函数，一般可以在这里做初始数据的获取')
      console.log(document.getElementsByClassName("myp")[0])//undefined
      console.log('接下来开始render，渲染出真实dom')
  },
   
  mounted:function(){ 
      console.log('mounted：此时，组件已经出现在页面中，数据、真实dom都已经处理好了,事件都已经挂载好了')
      console.log(document.getElementsByClassName("myp")[0])
      console.log('可以在这里操作真实dom等事情...')
  
   
  },
  beforeUpdate:function(){
    //这里不能更改数据，否则会陷入死循环
      console.log('beforeUpdate:重新渲染之前触发')
      console.log('然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染')         
  },
  updated:function(){
    //这里不能更改数据，否则会陷入死循环
      console.log('updated:数据已经更改完成，dom也重新render完成')
  },
  beforeDestroy:function(){
      console.log('beforeDestory:销毁前执行（$destroy方法被调用的时候就会执行）,一般在这里善后:清除计时器、清除非指令绑定的事件等等...')
      // clearInterval(this.$options.timer)
  },
  destroyed:function(){
      console.log('destroyed:组件的数据绑定、监听...都去掉了,只剩下dom空壳，这里也可以善后')
  } */
}